package com.weyoung.app.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.weyoung.app.config.VoiceEnrollmentSampleCodes;
import com.weyoung.app.dto.req.DifyDTO;
import com.weyoung.common.utils.DifyApiClient;
import com.weyoung.common.utils.UpLoadFiles;
import com.weyoung.common.model.dto.TXOssSetDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.*;
import com.weyoung.common.consatant.result.Result;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
import java.util.List;


@RestController
@RequestMapping("/api/dify")
@Slf4j
@RequiredArgsConstructor
@Tag(name = "Dify声音克隆接口")
public class DifyController {
    private final DifyApiClient difyClient;
    private final ObjectMapper mapper = new ObjectMapper();
    private final VoiceEnrollmentSampleCodes voiceEnrollmentSampleCodes;
    private final UpLoadFiles upLoadFiles;

    @Value("${cos.secret-id}")
    private String secretId;
    @Value("${cos.secret-key}")
    private String secretKey;
    @Value("${cos.bucket-name}")
    private String bucketName;
    @Value("${cos.endpoint}")
    private String endpoint;
    @Value("${cos.prefix}")
    private String prefix;

    @Autowired
    public DifyController(@Value("${dify.api-key}") String apiKey,
                          VoiceEnrollmentSampleCodes voiceEnrollmentSampleCodes,
                          UpLoadFiles upLoadFiles) {
        this.difyClient = new DifyApiClient(apiKey);
        this.voiceEnrollmentSampleCodes = voiceEnrollmentSampleCodes;
        this.upLoadFiles = upLoadFiles;
    }

    @Operation(summary = "生成克隆音频")
    @PostMapping("/generate")
    public Result generateText(@RequestBody DifyDTO difyDTO) {
        difyDTO.setTsc("你是一个去世不久的爸爸");
        difyDTO.setSp("one4");
        try {
            // 1. 构建请求体
            ObjectNode requestBody = buildRequestBody(difyDTO);

            // 2. 调用Dify API
            String response = difyClient.post("/workflows/run", requestBody.toString());

            // 3. 处理并合并所有text_chunk
            if(difyDTO.getIsFirst().equals("3")) {//文字
                return parseDifyWorkflowResponse(response);
            }
            if(difyDTO.getIsFirst().equals("1")) {//克隆
                return Result.success(response);

            }
            if(difyDTO.getIsFirst().equals("2")) {//语音
                // 调用VoiceEnrollmentSampleCodes处理文本
                difyDTO.setIsFirst("3");
                // 1. 构建请求体
                ObjectNode requestBody1 = buildRequestBody(difyDTO);

                // 2. 调用Dify API
                String response1 = difyClient.post("/workflows/run", requestBody1.toString());
                Result r = parseDifyWorkflowResponse(response1);
                byte[] audioData = voiceEnrollmentSampleCodes.deal((String) r.getData());

                // 创建MultipartFile对象
                MultipartFile multipartFile = new MockMultipartFile(
                        "file",
                        "audio.mp3",
                        "audio/mpeg",
                        audioData
                );

                // 上传到腾讯云
                TXOssSetDTO dto = new TXOssSetDTO(secretId, secretKey, bucketName, endpoint, prefix);
                String url = upLoadFiles.uploadToOss(multipartFile, dto, "Course-pictures");

                return Result.success(url);
            }
            return Result.success();
        } catch (Exception e) {
            log.error("Error in generateText: ", e);
            return Result.failure();
        }
    }

    private ObjectNode buildRequestBody(DifyDTO difyDTO) {
        ObjectNode requestBody = mapper.createObjectNode();
        ObjectNode inputs = mapper.createObjectNode();
        inputs.put("text", difyDTO.getText());
        inputs.put("tsc", difyDTO.getTsc());
        inputs.put("sp", difyDTO.getSp());
        inputs.put("isone", difyDTO.getIsFirst());
        inputs.put("url", difyDTO.getUrl());
        inputs.put("key", "j5zJsST5");
        requestBody.set("inputs", inputs);
        requestBody.put("response_mode", "streaming"); // 保持流式请求但同步返回
        requestBody.put("user", "abc-321");
        return requestBody;
    }
    public Result parseDifyWorkflowResponse(String response) {
        if (StringUtils.isBlank(response)) {
            return Result.failure();
        }

        ObjectMapper mapper = new ObjectMapper();
        List<String> eventLines = Arrays.asList(response.split("\n\n"));
        String finalResult = null;
        String errorMessage = null;

        try {
            for (String line : eventLines) {
                if (!line.startsWith("data: ")) {
                    continue;
                }

                JsonNode eventData = mapper.readTree(line.substring(6));
                String eventType = eventData.path("event").asText();

                if ("workflow_finished".equals(eventType)) {
                    JsonNode dataNode = eventData.path("data");
                    if (dataNode.isMissingNode()) {
                        continue;
                    }

                    JsonNode outputs = dataNode.path("outputs");
                    if (outputs.isObject() && outputs.has("result")) {
                        finalResult = outputs.path("result").asText();
                        break;
                    }
                }

                // 如果需要收集中间结果可以在此处理其他事件类型
                if ("text_chunk".equals(eventType)) {
                    // 处理流式文本片段
                    JsonNode textData = eventData.path("data");
                    String chunk = textData.path("text").asText();
                    // 这里可以添加文本拼接逻辑
                }
            }

            if (finalResult != null) {
                // 如果确定返回的是JSON格式
                try {
                    JsonNode httpResult = mapper.readTree(finalResult);
                    if (httpResult.has("mp3")) {
                        return Result.success(httpResult.path("mp3").asText());
                    }
                } catch (JsonProcessingException e) {
                    // 如果不是JSON格式，直接返回文本
                    return Result.success(finalResult);
                }
            }

            return Result.failure();
        } catch (Exception e) {
            log.error("Failed to parse Dify response", e);
            return Result.failure();
        }
    }
    public Result parseDifyWorkflowResponse1(String response) {
        if (StringUtils.isBlank(response)) {
            return Result.failure();
        }

        ObjectMapper mapper = new ObjectMapper();
        List<String> eventLines = Arrays.asList(response.split("\n\n"));
        String finalResult = null;

        try {
            for (String line : eventLines) {
                if (!line.startsWith("data: ")) continue;

                JsonNode eventData = mapper.readTree(line.substring(6));
                if ("workflow_finished".equals(eventData.path("event").asText())) {
                    JsonNode outputs = eventData.path("data").path("outputs");
                    if (outputs.has("result")) {
                        finalResult = outputs.path("result").asText();
                        break;
                    }
                }
            }

            if (finalResult == null) {
                return Result.failure();
            }

            // 解析嵌套的JSON结构
            JsonNode resultNode = mapper.readTree(finalResult);
            JsonNode outputNode = resultNode.path("output");
            if (!outputNode.isMissingNode() && outputNode.has("voice_id")) {
                String voiceId = outputNode.path("voice_id").asText();
                return Result.success(voiceId);
            }

            return Result.failure();
        } catch (JsonProcessingException e) {
            log.error("JSON parsing failed. Raw result: {}", finalResult, e);
            return Result.failure();
        } catch (Exception e) {
            log.error("Failed to parse Dify response", e);
            return Result.failure();
        }
    }
}
